﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using ESF.SharePoint.Entities;
using ESF.SharePoint.Formatters;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.SharePoint.Common.ServiceLocation;
using Microsoft.Office.Server.ActivityFeed;
using ESF.SharePoint.Utility;

namespace ESF.SharePoint.ActivityAggregators.Providers
{
    public class ColleagueAdditionActivityAggregationProvider : ActivityAggregatorBaseProvider
    {
        private string FormatterName = "CollegueAddictionPropertyFormatter";

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);

            // Get the ServiceLocatorConfig service from the service locator.
            IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
            IServiceLocatorConfig typeMappings =
                                  serviceLocator.GetInstance<IServiceLocatorConfig>();

            SPSite currentSite = SPContext.Current.Site;
            SPWeb currentWeb = currentSite.RootWeb;
            currentWeb.AllowUnsafeUpdates = true;
            typeMappings.Site = currentSite;
            typeMappings.RegisterTypeMapping<IActivityFormatter, CollegueAddictionPropertyFormatter>(FormatterName);
            SharePointServiceLocator.Reset();
        }

        public override List<CustomActivityEvent> ProcessActivities(List<CustomActivityEvent> source)
        {
            base.ActivityTypeId = 6;
            base.Formatter = FormatterName;
            //return base.ProcessActivities(source);

            //Dictionary<string, List<CustomActivityEvent>> eventsToRemove = new Dictionary<string, List<CustomActivityEvent>>();
            Dictionary<string, List<CustomActivityEvent>> temp = new Dictionary<string, List<CustomActivityEvent>>();
            List<CustomActivityEvent> eventsToRemove = new List<CustomActivityEvent>();

            // Getting only activities of the selected TypeId
            var events = from e in source
                         where e.ActivityTypeId == ActivityTypeId
                         select e;

            // Max item per user
            DateTime date = DateTime.MinValue;
            foreach (var customEvent in events)
            {

                if (date == DateTime.MinValue)
                    date = customEvent.CreationTime;

                // If current feed is related to new day reset counter
                if (IsInNewTimeSlot(date, customEvent))
                {
                    ProcessAndFormatEvent(temp);
                        
                    foreach (var a in temp)
                    {
                        eventsToRemove.AddRange(a.Value);
                    }
                        
                    temp = new Dictionary<string, List<CustomActivityEvent>>();
                    date = customEvent.CreationTime;
                }

                // Collect users that changed user profile properties
                List<CustomActivityEvent> activities;
                if (temp.ContainsKey(customEvent.Publisher.AccountName))
                {
                    activities = temp[customEvent.Publisher.AccountName];
                    activities.Add(customEvent);
                }
                else
                {
                    activities = new List<CustomActivityEvent>();
                    activities.Add(customEvent);
                    temp.Add(customEvent.Publisher.AccountName, activities);
                }
                    
            }

            // Update last feed with all users that changed user profile
            ProcessAndFormatEvent(temp);
            //eventsToRemove.Concat(temp).ToDictionary(e => e.Key, e => e.Value);
            foreach (var a in temp)
            {
                eventsToRemove.AddRange(a.Value);
            }

            // Remove items
            foreach (var eventToRemove in eventsToRemove)
            {
                source.Remove(eventToRemove);
            }

            return source;
        }

        public bool IsInNewTimeSlot(DateTime prevEventDate, CustomActivityEvent currentEvent)
        {
            if (prevEventDate.Date != currentEvent.CreationTime.Date)
            {
                if (IsEarlier(prevEventDate))
                    if (IsEarlier(currentEvent.CreationTime))
                    return false;

                return true;
            }
            
            return false;
        }

        private bool IsEarlier(DateTime date)
        {
            return DateTime.Now.AddDays(-2).Date >= date.Date;
        }

        private void ProcessAndFormatEvent(Dictionary<string, List<CustomActivityEvent>> eventsToRemove)
        {
            
            // Update last feed with all users that changed user profile
            //if (eventsToRemove.Values.Count > 1)
            //{
                // For every publisher adjast events
                foreach (var publisher in eventsToRemove)
                {
                    List<CustomActivityEvent> publisherEvents = publisher.Value;

                    // Compose collection of colleques
                    List<Link> colleguesAdded = new List<Link>();
                    foreach (var publisherEvent in publisherEvents)
                    {
                        if (publisherEvent.LinksList != null && publisherEvent.LinksList.Count > 0)
                            colleguesAdded.AddRange(publisherEvent.LinksList);
                        else
                            colleguesAdded.Add(publisherEvent.Link);
                    }

                    // Take out last event. It will be used to show events
                    CustomActivityEvent lastActivityOfTheDay = publisherEvents.ElementAt(publisherEvents.Count - 1);

                    // Remove all event of the users except the last one
                    publisherEvents.RemoveAt(publisherEvents.Count - 1);

                    IActivityFormatter formatter =
                        ServiceLocatorHelper.GetServiceInstance<IActivityFormatter>(SPContext.Current.Site, Formatter);

                    formatter.Format(lastActivityOfTheDay, colleguesAdded);
                }
            //}

            //return colleguesAdded;
        }
    }
}
